package guda.house.biz.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import guda.house.biz.beans.vo.BillExtVO;
import guda.house.biz.constants.CommonResultCode;
import guda.house.biz.enums.BooleanEnum;
import guda.house.biz.form.bill.BillDepositSearchForm;
import guda.house.biz.query.BillDepositQuery;
import guda.house.biz.query.BuildingQuery;
import guda.house.biz.query.SuiteQuery;
import guda.house.biz.query.UnitQuery;
import guda.house.biz.util.Transform;
import guda.house.biz.util.TransformHelper;
import guda.house.dal.dao.*;
import guda.house.dal.dataobject.BuildingDO;
import guda.house.dal.dataobject.SuiteDO;
import guda.house.dal.dataobject.UnitDO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import guda.house.biz.BillExtBiz;
import guda.house.dal.dataobject.BillExtDO;
import guda.grape.autogen.common.page.BaseQuery;
import guda.grape.autogen.common.page.BizResult;

public class BillExtBizImpl implements BillExtBiz{

    private final static Logger logger = LoggerFactory.getLogger(BillExtBizImpl.class);

    @Autowired
    private BillExtDAO billExtDAO;
    @Autowired
    private SuiteDAO suiteDAO;
    @Autowired
    private UnitDAO unitDAO;
    @Autowired
    private BuildingDAO buildingDAO;
    @Autowired
    private VillageDAO villageDAO;
    @Autowired
    private BillPayDAO billPayDAO;

    public BizResult detail(long id) {
        BizResult bizResult = new BizResult();
        try{
            BillExtDO billExtDO = billExtDAO.getBillExtById(id);
            bizResult.data.put("billExtDO", billExtDO);
            bizResult.success = true;
        }catch(Exception e){
            logger.error("query BillExt error",e);
        }
        return bizResult;
}

    public BizResult list(BaseQuery baseQuery) {
        BizResult bizResult = new BizResult();
        try {
            int totalCount = billExtDAO.countForPage(baseQuery);
            baseQuery.setTotalCount(totalCount);
            List<BillExtDO> billExtList = billExtDAO.selectForPage(baseQuery);
            bizResult.data.put("billExtList", billExtList);
            bizResult.data.put("query", baseQuery);
            bizResult.success = true;
        } catch (Exception e) {
            logger.error("view BillExt list error", e);
        }
            return bizResult;
     }

    public BizResult delete(long id) {
        BizResult bizResult = new BizResult();
        try {
            billExtDAO.delBillExtById(id);
            bizResult.success = true;
        } catch (Exception e) {
            logger.error("delete billExt error", e);
        }
        return bizResult;
    }

    public BizResult create(BillExtDO billExtDO) {
        BizResult bizResult = new BizResult();
        try {
            long id = billExtDAO.insert(billExtDO);
            bizResult.data.put("id", id);
            bizResult.success = true;
        } catch (Exception e) {
            logger.error("create BillExt error", e);
        }
        return bizResult;
    }

    @Override
    public BizResult update(BillExtDO billExtDO) {
        BizResult bizResult = new BizResult();
        try {
            billExtDAO.updateByIdSelective(billExtDO);
            bizResult.success = true;
        } catch (Exception e) {
            logger.error("update BillExt error", e);
        }
        return bizResult;
    }

    @Override
    public BizResult queryDepositList(BillDepositQuery billDepositQuery) {
        BizResult bizResult = new BizResult();
        if(billDepositQuery.getSuiteId()!=null){
            List<BillExtDO> billExtList = billExtDAO.selectForDeposit(billDepositQuery);
            int totalCount = billExtDAO.countForDeposit(billDepositQuery);
            billDepositQuery.setTotalCount(totalCount);
            bizResult.data.put("billExtVOList", convert(billExtList));
            bizResult.data.put("query", billDepositQuery);
            bizResult.success = true;
            return bizResult;
        }else if(billDepositQuery.getUnitId() != null){
            SuiteQuery suiteQuery = new SuiteQuery();
            suiteQuery.setUnitId(billDepositQuery.getUnitId());
            List<SuiteDO> suiteDOs = suiteDAO.selectForPage(suiteQuery);
            List<Long> suiteIdList= TransformHelper.transform(suiteDOs, new Transform<SuiteDO, Long>() {
                @Override
                public Long transform(SuiteDO object) {
                    return object.getSuiteId();
                }
            });
            billDepositQuery.setSuiteIdList(suiteIdList);
            List<BillExtDO> billExtList = billExtDAO.selectForDeposit(billDepositQuery);
            int totalCount = billExtDAO.countForDeposit(billDepositQuery);
            billDepositQuery.setTotalCount(totalCount);
            bizResult.data.put("billExtVOList", convert(billExtList));
            bizResult.data.put("query", billDepositQuery);
            bizResult.success = true;
            return bizResult;

        }else if(billDepositQuery.getBuildingId()!=null){
            UnitQuery unitQuery = new UnitQuery();
            unitQuery.setBuildingId(billDepositQuery.getBuildingId());
            List<UnitDO> unitDOs = unitDAO.selectForPage(unitQuery);
            List<Long> unitIdList = TransformHelper.transform(unitDOs, new Transform<UnitDO, Long>() {
                @Override
                public Long transform(UnitDO object) {
                    return object.getUnitId();
                }
            });

            SuiteQuery suiteQuery = new SuiteQuery();
            suiteQuery.setUnitIdList(unitIdList);
            List<SuiteDO> suiteDOs = suiteDAO.selectForPage(suiteQuery);
            List<Long> suiteIdList= TransformHelper.transform(suiteDOs, new Transform<SuiteDO, Long>() {
                @Override
                public Long transform(SuiteDO object) {
                    return object.getSuiteId();
                }
            });
            billDepositQuery.setSuiteIdList(suiteIdList);
            List<BillExtDO> billExtList = billExtDAO.selectForDeposit(billDepositQuery);
            int totalCount = billExtDAO.countForDeposit(billDepositQuery);
            billDepositQuery.setTotalCount(totalCount);
            bizResult.data.put("billExtVOList", convert(billExtList));
            bizResult.data.put("query", billDepositQuery);
            bizResult.success = true;
            return bizResult;
        }else if(billDepositQuery.getVillageId()!=null){
            BuildingQuery buildingQuery = new BuildingQuery();
            buildingQuery.setPageSize(10000);
            buildingQuery.setVillageId(billDepositQuery.getVillageId());
            List<BuildingDO> buildingDOs = buildingDAO.selectForPage(buildingQuery);
            List<Long> buildingIdList= TransformHelper.transform(buildingDOs, new Transform<BuildingDO, Long>() {
                @Override
                public Long transform(BuildingDO object) {
                    return object.getBuildingId();
                }
            });

            UnitQuery unitQuery = new UnitQuery();
            unitQuery.setPageSize(10000);
            unitQuery.setBuildingIdList(buildingIdList);
            List<UnitDO> unitDOs = unitDAO.selectForPage(unitQuery);
            List<Long> unitIdList = TransformHelper.transform(unitDOs, new Transform<UnitDO, Long>() {
                @Override
                public Long transform(UnitDO object) {
                    return object.getUnitId();
                }
            });

            SuiteQuery suiteQuery = new SuiteQuery();
            suiteQuery.setPageSize(10000);
            suiteQuery.setUnitIdList(unitIdList);
            List<SuiteDO> suiteDOs = suiteDAO.selectForPage(suiteQuery);
            List<Long> suiteIdList= TransformHelper.transform(suiteDOs, new Transform<SuiteDO, Long>() {
                @Override
                public Long transform(SuiteDO object) {
                    return object.getSuiteId();
                }
            });
            billDepositQuery.setSuiteIdList(suiteIdList);
            List<BillExtDO> billExtList = billExtDAO.selectForDeposit(billDepositQuery);
            int totalCount = billExtDAO.countForDeposit(billDepositQuery);
            billDepositQuery.setTotalCount(totalCount);
            bizResult.data.put("billExtVOList", convert(billExtList));
            bizResult.data.put("query", billDepositQuery);
            bizResult.success = true;
            return bizResult;
        }
        List<BillExtDO> billExtList = billExtDAO.selectForDeposit(billDepositQuery);
        int totalCount = billExtDAO.countForDeposit(billDepositQuery);
        billDepositQuery.setTotalCount(totalCount);
        bizResult.data.put("billExtVOList", convert(billExtList));
        bizResult.data.put("query", billDepositQuery);
        bizResult.success = true;
        return bizResult;

    }

    private List<BillExtVO> convert(List<BillExtDO> billExtDOList){
        if(billExtDOList == null){
            return Collections.emptyList();
        }
        List<BillExtVO> billExtVOList = new ArrayList<BillExtVO>(billExtDOList.size());
        for(BillExtDO billExtDO:billExtDOList){
            BillExtVO billExtVO = new BillExtVO();
            billExtVO.setBillExtDO(billExtDO);
            billExtVO.setBillPayDO(billPayDAO.getBillPayById(billExtDO.getBillPayId()));
            billExtVOList.add(billExtVO);
        }
        return billExtVOList;
    }

    @Override
    public BizResult initSearchForm(BillDepositSearchForm billDepositSearchForm) {
        BizResult bizResult = new BizResult();
        if(billDepositSearchForm.getVillageId() == null){
            bizResult.success = true;
            return bizResult;
        }
        BuildingQuery buildingQuery = new BuildingQuery();
        buildingQuery.setPageSize(10000);
        buildingQuery.setVillageId(billDepositSearchForm.getVillageId());
        List<BuildingDO> buildingDOs = buildingDAO.selectForPage(buildingQuery);
        bizResult.data.put("buildingList", buildingDOs);
        if(billDepositSearchForm.getBuildingId() == null){
            bizResult.success = true;
            return bizResult;
        }
        UnitQuery unitQuery = new UnitQuery();
        unitQuery.setPageSize(10000);
        unitQuery.setBuildingId(billDepositSearchForm.getBuildingId());
        List<UnitDO> unitDOs = unitDAO.selectForPage(unitQuery);
        bizResult.data.put("unitList", unitDOs);

        if(billDepositSearchForm.getUnitId() == null){
            bizResult.success = true;
            return bizResult;
        }

        SuiteQuery suiteQuery = new SuiteQuery();
        suiteQuery.setPageSize(10000);
        suiteQuery.setUnitId(billDepositSearchForm.getUnitId());
        List<SuiteDO> suiteDOs = suiteDAO.selectForPage(suiteQuery);
        bizResult.data.put("suiteList", suiteDOs);
        bizResult.success = true;
        return bizResult;
    }

    @Override
    public BizResult refund(long id) {
        BizResult bizResult = new BizResult();
        BillExtDO billExtById = billExtDAO.getBillExtById(id);
        if(billExtById == null){
            bizResult.code = CommonResultCode.RECORD_NOT_FOUND;
            return bizResult;
        }
        billExtById.setIsRefund(BooleanEnum.TRUE.getVal());
        billExtDAO.updateByIdSelective(billExtById);
        bizResult.success = true;
        return bizResult;
    }

    @Override
    public BizResult reverse(long id) {
        BizResult bizResult = new BizResult();
        BillExtDO billExtById = billExtDAO.getBillExtById(id);
        if(billExtById == null){
            bizResult.code = CommonResultCode.RECORD_NOT_FOUND;
            return bizResult;
        }
        billExtById.setOffsetStatus(BooleanEnum.TRUE.getVal());
        billExtDAO.updateByIdSelective(billExtById);
        bizResult.success = true;
        return bizResult;
    }


}
